package factory.one.controller;

import com.alibaba.fastjson2.JSON;
import factory.one.base.Constant;
import factory.one.entity.*;
import factory.one.pojo.common.Page;
import factory.one.pojo.common.SqlCondition;
import factory.one.service.*;
import factory.one.utils.SecurityUtil;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.sql.Types;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static factory.one.base.Constant.BD_100;

/**
 * @author sk.z
 * 2023/7/5
 * 销售服务
 **/
@Controller
@RequestMapping("/sale")
public class SaleController {

    private final OrderService orderService;
    private final BatchService batchService;
    private final CustomService customService;
    private final ProductService productService;
    private final RefundService refundService;
    private final CountService countService;

    public SaleController(OrderService orderService,
                          BatchService batchService,
                          CustomService customService,
                          ProductService productService,
                          RefundService refundService,
                          CountService countService) {
        this.orderService = orderService;
        this.batchService = batchService;
        this.customService = customService;
        this.productService = productService;
        this.refundService = refundService;
        this.countService = countService;
    }

    @GetMapping("/add.html")
    public String addHtml(Model model) {
        List<Custom> customList = customService.listByUser(SecurityUtil.isAdmin() ? null : SecurityUtil.getUserName());
        List<Product> productList = productService.listNormal();
        model.addAttribute("customList", customList);
        model.addAttribute("productList", productList);
        return "sale/add";
    }

    @ResponseBody
    @PostMapping("/add")
    @Transactional
    public String add(@RequestParam String customId,
                      @RequestParam BigDecimal amount,
                      @RequestParam String batchJson) {
        String userName = SecurityContextHolder.getContext().getAuthentication().getName();

        List<Batch> batches = null;
        int orderNum = 0;
        if (StringUtils.hasText(batchJson)) {
            batches = JSON.parseArray(batchJson, Batch.class);
            for (Batch b : batches) {
                orderNum += b.getOrderNum();
            }
        }

        Order order = new Order();
        order.setCustomId(Long.valueOf(customId));
        order.setConfirm(false);
        order.setOrderNum(orderNum);
        order.setContractAmount(amount.multiply(BD_100).longValue());
        order.setCreateUser(userName);
        Long orderId = orderService.add(order);

        if (!CollectionUtils.isEmpty(batches)) {
            for (Batch b : batches) {
                b.setOrderId(orderId);
                b.setProduceUsers("");
                batchService.add(b);
            }
        }
        return "ture";
    }

    //stage 0-未开始 1-准备 2-开始 3-完成
    @GetMapping("/list.html")
    public String listHtml(@RequestParam(defaultValue = "1") Integer page,
                           @RequestParam(defaultValue = "10") Integer size,
                           Model model) {
        List<Order> list;
        int count;
        if (SecurityUtil.isAdmin()) {
            list = orderService.list(page, size);
            count = orderService.listCount();
        } else {
            List<SqlCondition> sqlConditions = Collections.singletonList(new SqlCondition("create_user = ? ", SecurityUtil.getUserName(), Types.VARCHAR));
            list = orderService.listByCondition(page, size, sqlConditions);
            count = orderService.countByCondition(sqlConditions);
        }
        trans(list);
        model.addAttribute("page", new Page<>(list, count, page, size));
        return "sale/list";
    }

    @GetMapping("/detail.html")
    public String detailHtml(@RequestParam Long orderId, Model model) {
        Order order = orderService.getById(orderId);
        if (!SecurityUtil.isAdmin()){
            if (!order.getCreateUser().equals(SecurityUtil.getUserName())){
                return "/403";
            }
        }
        Custom custom = customService.getById(order.getCustomId());
        order.setCustomName(custom.getName());
        model.addAttribute("order", order);

        List<Batch> batchList = batchService.list(orderId);
        transBatch(batchList);
        model.addAttribute("batchList", batchList);
        model.addAttribute("corporate", Constant.CORPORATE_NAME);
        return "sale/detail";
    }

    @GetMapping("/edit.html")
    public String editHtml(@RequestParam Long orderId, Model model) {
        Order order = orderService.getById(orderId);
        if (!SecurityUtil.isAdmin()){
            if (!order.getCreateUser().equals(SecurityUtil.getUserName())){
                return "/403";
            }
        }
        model.addAttribute("order", order);
        model.addAttribute("batchList", batchService.list(orderId));
        model.addAttribute("customList", customService.listByUser(SecurityUtil.isAdmin() ? null : SecurityUtil.getUserName()));
        model.addAttribute("productList", productService.listNormal());
        return "sale/edit";
    }

    @ResponseBody
    @PostMapping("/edit")
    @Transactional
    public String edit(@RequestParam Long id,
                       @RequestParam Long customId,
                       @RequestParam BigDecimal amount,
                       @RequestParam String batchJson) {
        Order order = orderService.getById(id);
        if (null==order){
            return "{\"code\":0,\"message\":\"订单不存在，请联系管理员！\"}";
        }else if (order.getConfirm()||order.getStatus()==0){
            return "{\"code\":0,\"message\":\"无权限修改，请联系管理员！\"}";
        }

        int orderSum = 0;
        if (StringUtils.hasText(batchJson)) {
            List<Batch> batches = JSON.parseArray(batchJson, Batch.class);
            for (Batch b : batches) {
                b.setProduceUsers("");
                orderSum += b.getOrderNum();
            }
            batchService.updateList(id, batches);
        }

        Order update = new Order();
        update.setId(id);
        update.setCustomId(customId);
        update.setOrderNum(orderSum);
        update.setContractAmount(amount.multiply(BD_100).longValue());
        orderService.update(update);
        countService.submit(id);
        return "{\"code\":1,\"message\":\"更新成功！\"}";
    }

    @GetMapping("/refund.html")
    public String refundHtml(@RequestParam Long orderId, Model model) {
        Order order = orderService.getById(orderId);
        Custom custom = customService.getById(order.getCustomId());
        order.setCustomName(custom.getName());
        List<Batch> batchList = batchService.list(orderId);
        transBatch(batchList);
        model.addAttribute("order", order);
        model.addAttribute("batchList", batchList);

        List<Refund> refundList = refundService.listByOrder(orderId);
        if (CollectionUtils.isEmpty(refundList)) {
            model.addAttribute("refundList", null);
        } else {
            Map<Long, String> batchProductNameMap = batchList.stream().collect(Collectors.toMap(Batch::getId, Batch::getProductName, (k1, k2) -> k1));
            for (Refund refund : refundList) {
                refund.setProductName(batchProductNameMap.get(refund.getBatchId()));
            }
            model.addAttribute("refundList", refundList);
        }
        return "sale/refund";
    }

    @ResponseBody
    @PostMapping("/refund")
    public Long refund(@RequestParam Long id, @RequestParam Integer refundNumber) {
        Long orderId = batchService.getById(id).getOrderId();
        Refund r = new Refund();
        r.setOrderId(orderId);
        r.setBatchId(id);
        r.setNumber(refundNumber);
        r.setCreateUser(SecurityContextHolder.getContext().getAuthentication().getName());
        r.setCreateTime(new Date());
        Long result = refundService.add(r);
        countService.submit(orderId);
        return result;
    }

    @ResponseBody
    @PostMapping("/upperLine")
    public String upperLine(@RequestParam Long id) {
        return Integer.toString(orderService.updateConfirm(id, true));
    }

    @ResponseBody
    @PostMapping("/cancel")
    public String cancel(@RequestParam Long orderId) {
        return Integer.toString(orderService.del(orderId));
    }

    private void trans(List<Order> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (Order order : list) {
            Custom custom = customService.getById(order.getCustomId());
            order.setCustomName(custom.getName());
//            StageUtil.build(order);
        }
    }

    private void transBatch(List<Batch> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (Batch batch : list) {
            Product product = productService.getById(batch.getProductId());
            batch.setProductName(product.getName());
            batch.setAmount(batch.getOrderNum() * batch.getPrice());
            batch.setProduceGap(Math.max(0, batch.getOrderNum() - batch.getProduceNum()));
            batch.setSendGap(Math.max(0, batch.getOrderNum() - batch.getSendNum()));
        }
    }

}
